/*
 * algebraBasic.h
 *
 *  Created on: 27-nov.-2013
 *      Author: Axel
 */


#ifndef ALGEBRABASIC_H_
#define ALGEBRABASIC_H_

//vector of length M and N*/

class Vector4f
{
public:
    float x;
    float y;
    float z;
    float w;

    Vector4f() {
    	x = 0;
    	y = 0;
    	z = 0;
    	w = 0;
    }

    Vector4f(float _x, float _y, float _z, float _w)
    {
        x = _x;
        y = _y;
        z = _z;
        w = _w;
    }

    float operator*(const Vector4f& Right) const;
    Vector4f operator*(const float& right) const;

    Vector4f operator+(const Vector4f& Right) const;
    Vector4f operator-(const Vector4f& Right) const;
    Vector4f operator-() const;

    Vector4f& operator+=(const Vector4f& right);
    Vector4f& operator-=(const Vector4f& right);

    long length();
};

class Vector3f
{
public:
    float x;
    float y;
    float z;

    Vector3f() {
    	x = 0;
    	y = 0;
    	z = 0;
    }

    Vector3f(float _x, float _y, float _z)
    {
        x = _x;
        y = _y;
        z = _z;
    }

    float operator*(const Vector3f& Right) const;
    Vector3f operator+(const Vector3f& Right) const;
    Vector3f operator-(const Vector3f& Right) const;
    Vector3f operator-() const;

    Vector3f& operator+=(const Vector3f& right);
    Vector3f& operator-=(const Vector3f& right);

    float* getArray();

    Vector3f crossProd(Vector3f right);
    long length();

    bool operator<(Vector3f& right);
    bool operator>(Vector3f& right);
    bool operator<=(Vector3f& right);
    bool operator>=(Vector3f& right);
};

//extra functions:
Vector4f mix(Vector4f A, Vector4f B, Vector4f t);

Vector3f mixLine(Vector3f a, Vector3f b, float t);

Vector4f quadratic_bezier(Vector4f A, Vector4f B, Vector4f C, float t);
Vector4f cubic_bezier(Vector4f A, Vector4f B, Vector4f C, Vector4f D, float t);
Vector4f quintic_bezier(Vector4f A, Vector4f B, Vector4f C, Vector4f D, Vector4f E, float t);
Vector4f cubic_bspline_10(Vector4f CP[10], float t);

//matrixes
class Matrix4f
{
public:
    float m[4][4];

    Matrix4f() {
    	InitIdentity();
    }

    Matrix4f(Vector4f a, Vector4f b, Vector4f c, Vector4f d) {
    	m[0][0] = a.x;  	m[0][1] = a.y;     	m[0][2] = a.z;    	m[0][3] = a.w;
    	m[1][0] = b.x;  	m[1][1] = b.y;     	m[1][2] = b.z;    	m[1][3] = b.w;
    	m[2][0] = c.x;  	m[2][1] = c.y;     	m[2][2] = c.z;    	m[2][3] = c.w;
    	m[3][0] = d.x;  	m[3][1] = d.y;     	m[3][2] = d.z;    	m[3][3] = d.w;
    }

    void InitIdentity();

    bool operator==(const Matrix4f& Right) const;

    Matrix4f operator*(const Matrix4f& Right) const;
    Matrix4f operator+(const Matrix4f& Right) const;
    Matrix4f operator-(const Matrix4f& Right) const;
    Matrix4f operator-() const;

    Matrix4f& operator+=(const Matrix4f& right);
    Matrix4f& operator-=(const Matrix4f& right);

    Vector3f matVector(Vector3f vec);

};

class MatrixNMf {
	float** m;
	int row;
	int col;

	MatrixNMf() {
		m = new float*[4];
		for(int i = 0; i < 4; i++)
			m[i] = new float[4];

		for(int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				m[i][j] = 0.0f;

		row = 4;
		col = 4;
	}

	MatrixNMf(int _row, int _col) {
		m = new float*[_row];
		for(int i = 0; i < 4; i++)
			m[i] = new float[_col];

		for(int i=0;i<_row;i++)
		    for(int j=0;j<_col;j++)
		    	m[i][j] = 0.0f;

		row = _row;
		col = _col;
	}

	inline void InitIdentity();

	MatrixNMf operator*(const MatrixNMf& Right) const;
	MatrixNMf operator+(const MatrixNMf& Right) const;
	MatrixNMf operator-(const MatrixNMf& Right) const;
	MatrixNMf operator-() const;

	MatrixNMf& operator+=(const MatrixNMf& right);
	MatrixNMf& operator-=(const MatrixNMf& right);
};

class Quaternion
{
public:
	double x,y,z,w;

	Quaternion() {
		x = 0;
		y = 0;
		z = 0;
		w = 0;
	}

	Quaternion(double x, double y, double z, double w) {
		this->x = x;
		this->y = y;
		this->z = z;
		this->w = w;
	}

	Quaternion operator*(const Quaternion& Right) const;
	Quaternion operator+(const Quaternion& Right) const;
	Quaternion operator-(const Quaternion& Right) const;
	Quaternion operator-() const;

	double magnitude();

	Quaternion& operator+=(const Quaternion& right);
	Quaternion& operator-=(const Quaternion& right);
};

#endif /* ALGEBRABASIC_H_ */
